package cn.tedu.micro.service.order.controller;

import cn.tedu.micro.service.common.JsonResult;
import cn.tedu.micro.service.order.sentinel.OrderBlockError;
import cn.tedu.micro.service.order.sentinel.OrderFallbackError;
import cn.tedu.micro.service.order.service.OrderService;
import cn.tedu.micro.service.pojo.param.OrderAddParam;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import io.seata.core.exception.TransactionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/order")
public class OrderController {
    @Autowired
    private OrderService orderService;

    //新增订单
    @PostMapping("/add")
    @SentinelResource(value = "and-order",
            blockHandlerClass = OrderBlockError.class,blockHandler = "blockError",
            fallbackClass = OrderFallbackError.class,fallback = "fallbackError")
    public JsonResult addOrder(OrderAddParam orderAddParam) {
        Boolean result = orderService.addOrder(orderAddParam);
        if(!result)
            return  JsonResult.fail("新增失败");
        return JsonResult.ok("新增成功");
    }
    //查询订单
    @GetMapping("/select")
//    @SentinelResource(value = "order-select",
//            blockHandler = "blackError",fallback = "fallbackError")
    @SentinelResource(value = "select-order",
            blockHandlerClass = OrderBlockError.class,blockHandler = "blockError",
            fallbackClass = OrderFallbackError.class,fallback = "fallbackError")
    public String selectOrder(){
        //为了出现降级，故意设计请求处理失败，80%会失败
        if(Math.random()<0.8){
            System.out.println(1/0);
        }
        //TODO 测试使用
        return "访问成功";
    }

    //自定义限流方法
    /**
     * 1.访问修饰符需要是public
     * 2.返回值类型需要和被限流的方法保持一致
     * 3.方法名是@SentinelResource注解中的blockHandler的值
     * 4.参数列表是和被限流的方法保持一致，除此之外还需额外添加一个BlockException的异常
     */
//    public String blackError(BlockException e){
//        //限流方法一般直接返回限流信息即可
//        return "您被限流了！！！"+e.toString();
//    }
    //自定义降级方法
    /**
     * 1.访问修饰符需要是public
     * 2.返回值类型需要和被降级的方法保持一致
     * 3.方法名是@SentinelResource注解中的fallback的值
     * 4.参数列表是和被降级的方法保持一致，还可以添加一个异常的参数
     */
//    public String fallbackError(){
//        //降级方法的可以返回提示信息，也可以做其他的处理
////        OrderAddParam orderAddParam = new OrderAddParam();
////        orderAddParam.setProductCode("PU1000");
////        orderAddParam.setOrderSn("fallback");
////        orderAddParam.setCount(2);
////        orderAddParam.setUserId("UU200");
////        orderAddParam.setTotalMoney(500);
////        orderService.addOrder(orderAddParam);
//        return "您被降级了";
//    }
}
